package com.ymatou.iapi.trading.operate.testcase;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.ymatou.iapi.trading.operate.parameter.Order;
import com.ymatou.iapi.trading.operate.parameter.PlaceOrderResp;
import com.ymatou.iapi.trading.operate.parameter.PlaceOrderService;
import com.ymatou.iapi.trading.operate.parameter.enums.LogisticsTypeEnum;
import com.ymatou.iapi.trading.operate.parameter.req.ApplySalesRefundRequestBean;
import com.ymatou.operate.trading.api.parameter.AutoConfirmReceiveBean;
import com.ymatou.operate.trading.api.parameter.FrozenOrUnFrozenOrderBean;
import com.ymatou.operate.trading.api.service.AutoConfirmReceiveCall;
import com.ymatou.operate.trading.api.service.FrozenOrUnFrozenOrderCall;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymt.utils.tag.P3;
import com.ymttest.business.service.OrderCallService;
import com.ymttest.business.service.PayGateWayCallService;
import com.ymttest.database.sqlwapper.DefaultWapper;
import com.ymttest.utils.DataUtil;

/**
 * 买家确认收货 FreeMaker Template自动生成代码
 */
@TestSuite
public class Ts_AutoConfirmReceive {

	private static AutoConfirmReceiveBean confirmreceivebean;
	private static AutoConfirmReceiveCall confirmreceivecall;

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("自动确认收货");
	}

	@Before
	public void caseUp() {

		confirmreceivebean = new AutoConfirmReceiveBean();
		confirmreceivecall = new AutoConfirmReceiveCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(confirmreceivecall.getOpurl());
	}

	@After
	public void caseDown() {
		Logger.end();
	}

	// 订单投诉维权(冻结和解冻)接口
	private void frozenOrder(boolean isFrozen, Integer orderId, int sellerId) {
		FrozenOrUnFrozenOrderBean frozenorunfrozenorderBean = new FrozenOrUnFrozenOrderBean();
		FrozenOrUnFrozenOrderCall frozenorunfrozenorderCall = new FrozenOrUnFrozenOrderCall();
		frozenorunfrozenorderBean.setOrderId(orderId);
		frozenorunfrozenorderBean.setUserId(sellerId);
		frozenorunfrozenorderBean.setIsFrozen(isFrozen);
		frozenorunfrozenorderCall.setData(false, frozenorunfrozenorderBean);
		try {
			frozenorunfrozenorderCall.callService();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_AutoConfirmReceive_001() {
		Logger.start(true, "自动确认收货成功");
		try {

			PlaceOrderService.logisticsType = LogisticsTypeEnum.US;
			// 创建订单
			Logger.comment("前置数据准备");
			PlaceOrderResp placeOrderResp = PlaceOrderService.acceptOrder();

			int orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			int sellerId = placeOrderResp.getOrderList().get(0).getSellerId();

			new OrderCallService().dispatched(orderId, sellerId);

			// 修改发货时间为25天前，使其能自动确认收货
			new DefaultWapper().updateOrderDispathTimeByOrderId(orderId);
			// 冻结时间为当前时间20天前，使其能自动确认收货
			new DefaultWapper().updateOrderFrozenByOrderId(orderId);

			Logger.comment("前置数据准备结束");
			// 确认收货请求
			confirmreceivebean.setOrderId(orderId);
			// 发送请求
			confirmreceivecall.setData(confirmreceivebean);
			confirmreceivecall.callService();
			Logger.verifyEquals("ok", confirmreceivecall.getReturnData(),
					"验证接口返回");
			// 数据库验证
			DefaultWapper database = new DefaultWapper();
			Logger.verifyEquals(4, database.getTradingStatus(orderId),
					"验证订单交易状态");

			Logger.verifyEquals(
					1,
					database.selectOrderTradingStatusByOrderIdAndTradingStatus(
							orderId, 4).size(), "验证TradingStatus表中 增加一条订单操作记录");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_AutoConfirmReceive_002() {
		Logger.start(false, "重复自动确认收货");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			PlaceOrderResp placeOrderResp = PlaceOrderService.placeOrder4();

			int orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			int sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			int userId = placeOrderResp.getUserId();
			int tradingId = placeOrderResp.getTradingId();

			OrderCallService orderCallService = new OrderCallService();
			// 应付款全金额
			BigDecimal totalPrice = orderCallService
					.getNeedPrePayAmountOfCash(orderId);
			// 支付订单
			orderCallService.orderPayRequest(userId, totalPrice, tradingId);
			// 接单
			orderCallService.acceptOrder(orderId, sellerId);
			// 商家发货
			orderCallService.dispatched(orderId, sellerId);

			// 修改发货时间为10天前，使其能自动确认收货
			new DefaultWapper().updateOrderDispathTimeByOrderId(orderId);
			// 冻结时间为当前时间20天前，使其能自动确认收货
			new DefaultWapper().updateOrderFrozenByOrderId(orderId);

			Logger.comment("前置数据准备结束");
			// 确认收货请求
			confirmreceivebean.setOrderId(orderId);
			// 发送请求
			confirmreceivecall.setData(confirmreceivebean);
			confirmreceivecall.callService();
			// 发送请求
			Logger.comment("重复请求");
			confirmreceivecall.callService();
			Logger.verifyEquals("ok", confirmreceivecall.getReturnData(),
					"验证接口返回");
			// 数据库验证
			DefaultWapper database = new DefaultWapper();
			Logger.verifyEquals(4, database.getTradingStatus(orderId),
					"验证订单交易状态");
			Logger.verifyEquals(
					1,
					database.selectOrderTradingStatusByOrderIdAndTradingStatus(
							orderId, 4).size(), "验证TradingStatus表中 增加一条订单操作记录");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_AutoConfirmReceive_003() {
		Logger.start(false, "订单号不存在");
		try {
			Integer orderId = 1111;
			confirmreceivebean.setOrderId(orderId);
			// 发送请求
			confirmreceivecall.setData(confirmreceivebean);
			confirmreceivecall.callService();
			Logger.verifyEquals("ok", confirmreceivecall.getReturnData(),
					"验证接口返回");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_AutoConfirmReceive_004() {
		Logger.start(false, "订单号为null");
		try {
			int orderId = 1111;
			// confirmreceivebean.setOrderId(orderId);
			// 发送请求
			confirmreceivecall.setData(confirmreceivebean);
			confirmreceivecall.callService();
			Logger.verifyEquals("fail", confirmreceivecall.getReturnData(),
					"验证接口返回");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_AutoConfirmReceive_005() {
		Logger.start(true, "当前订单为退货退款中,自动确认收货失败");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			OrderCallService orderCallService = new OrderCallService();
			PlaceOrderResp placeOrderResp = new OrderCallService()
					.createM2cOrder();

			Integer orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			int sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			int userId = placeOrderResp.getUserId();
			int tradingId = placeOrderResp.getTradingId();
			// 保留两位小数
			BigDecimal totalPrice = placeOrderResp.getPayAmount();// 支付金额

			// 支付订单
			orderCallService.orderPayRequest(userId, totalPrice, tradingId);
			// 接单
			orderCallService.acceptOrder(orderId, sellerId);
			// 商家发货
			orderCallService.dispatched(orderId, sellerId);
			// 退款中
			orderCallService.applySalesRefundRequestInJava(orderId);
			Logger.comment("前置数据准备结束");
			// 确认收货请求
			confirmreceivebean.setOrderId(orderId);
			// 发送请求
			confirmreceivecall.setData(confirmreceivebean);
			confirmreceivecall.callService();
			Logger.verifyEquals("fail", confirmreceivecall.getReturnData(),
					"验证接口返回");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_AutoConfirmReceive_006() {
		Logger.start(true, "当前订单还未到自动化确认收货时间,自动确认收货失败");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			OrderCallService orderCallService = new OrderCallService();
			PlaceOrderResp placeOrderResp = new OrderCallService()
					.createM2cOrder();

			Integer orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			int sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			int userId = placeOrderResp.getUserId();
			int tradingId = placeOrderResp.getTradingId();
			// 保留两位小数
			BigDecimal totalPrice = placeOrderResp.getPayAmount();// 支付金额
			// 支付订单
			orderCallService.orderPayRequest(userId, totalPrice, tradingId);
			// 接单
			orderCallService.acceptOrder(orderId, sellerId);
			// 商家发货
			orderCallService.dispatched(orderId, sellerId);
			// 退款中
			orderCallService.applySalesRefundRequestInJava(orderId);
			Logger.comment("前置数据准备结束");
			// 确认收货请求
			confirmreceivebean.setOrderId(orderId);
			// 发送请求
			confirmreceivecall.setData(confirmreceivebean);
			confirmreceivecall.callService();
			Logger.verifyEquals("fail", confirmreceivecall.getReturnData(),
					"验证接口返回");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_AutoConfirmReceive_007() {
		Logger.start(true, "当前订单为投诉冻结中，自动确认收货失败");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			OrderCallService orderCallService = new OrderCallService();
			PlaceOrderResp placeOrderResp = new OrderCallService()
					.createM2cOrder();

			Integer orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			int sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			int userId = placeOrderResp.getUserId();
			int tradingId = placeOrderResp.getTradingId();
			// 保留两位小数
			BigDecimal totalPrice = placeOrderResp.getPayAmount();// 支付金额
			// 支付订单
			orderCallService.orderPayRequest(userId, totalPrice, tradingId);
			// 接单
			orderCallService.acceptOrder(orderId, sellerId);
			// 商家发货
			orderCallService.dispatched(orderId, sellerId);
			// 投诉维权冻结中
			frozenOrder(true, orderId, sellerId);
			Logger.comment("前置数据准备结束");
			// 确认收货请求
			confirmreceivebean.setOrderId(orderId);
			// 发送请求
			confirmreceivecall.setData(confirmreceivebean);
			confirmreceivecall.callService();
			Logger.verifyEquals("fail", confirmreceivecall.getReturnData(),
					"验证接口返回");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_AutoConfirmReceive_008() {
		Logger.start(true, "当前订单为投诉解冻,自动确认收货成功");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			PlaceOrderResp placeOrderResp = PlaceOrderService.placeOrder4();

			int orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			int sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			int userId = placeOrderResp.getUserId();
			int tradingId = placeOrderResp.getTradingId();

			OrderCallService orderCallService = new OrderCallService();
			// 应付款全金额
			BigDecimal totalPrice = orderCallService
					.getNeedPrePayAmountOfCash(orderId);
			// 支付订单
			orderCallService.orderPayRequest(userId, totalPrice, tradingId);
			// 接单
			orderCallService.acceptOrder(orderId, sellerId);
			// 商家发货
			orderCallService.dispatched(orderId, sellerId);
			// 投诉维权冻结中
			frozenOrder(false, orderId, sellerId);
			// 修改发货时间为10天前，使其能自动确认收货
			new DefaultWapper().updateOrderDispathTimeByOrderId(orderId);
			// 冻结时间为当前时间20天前，使其能自动确认收货
			new DefaultWapper().updateOrderFrozenByOrderId(orderId);
			Logger.comment("前置数据准备结束");
			// 确认收货请求
			confirmreceivebean.setOrderId(orderId);
			// 发送请求
			confirmreceivecall.setData(confirmreceivebean);
			confirmreceivecall.callService();
			Logger.verifyEquals("ok", confirmreceivecall.getReturnData(),
					"验证接口返回");
			// 数据库验证
			DefaultWapper database = new DefaultWapper();
			Logger.verifyEquals(4, database.getTradingStatus(orderId),
					"验证订单交易状态");
			Logger.verifyEquals(
					1,
					database.selectOrderTradingStatusByOrderIdAndTradingStatus(
							orderId, 4).size(), "验证TradingStatus表中 增加一条订单操作记录");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_AutoConfirmReceive_009() {
		Logger.start(true, "一个主单下面多个不同买手子订单,子订单依次自动确认收货,校验交易结算表");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			OrderCallService orderCallService = new OrderCallService();

			PlaceOrderResp placeOrderResp = PlaceOrderService.placeOrder3();

			List<Order> orderIds = placeOrderResp.getOrderList();

			int sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			int userId = placeOrderResp.getUserId();
			int tradingId = placeOrderResp.getTradingId();

			BigDecimal totalAmount = placeOrderResp.getPayAmount();// 支付金额

			// 支付订单
			orderCallService.orderPayRequest(userId, totalAmount, tradingId);

			for (int i = 0; i < orderIds.size(); i++) {

				int orderId = orderIds.get(i).getOrderId();
				// 接单
				orderCallService.acceptOrder(orderId, sellerId);
				// 发货
				orderCallService.dispatched(orderId, sellerId);
				// 修改发货时间为10天前，使其能自动确认收货
				new DefaultWapper().updateOrderDispathTimeByOrderId(orderId);
				// 冻结时间为当前时间20天前，使其能自动确认收货
				new DefaultWapper().updateOrderFrozenByOrderId(orderId);
			}
			Logger.comment("前置数据准备结束");
			DefaultWapper database = new DefaultWapper();
			for (int i = 0; i < orderIds.size(); i++) {
				Integer orderId = orderIds.get(i).getOrderId();

				// 确认收货请求
				confirmreceivebean.setOrderId(orderId);
				// 发送请求
				Logger.comment("订单:" + orderId + "确认收货");
				confirmreceivecall.setData(confirmreceivebean);
				confirmreceivecall.callService();
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_AutoConfirmReceive_010() {
		Logger.start(true, "下单之后,确认收货前,退一部分款,然后自动确认收货,校验结算单");
		try {
			// 创建订单
			PlaceOrderResp placeOrderResp = PlaceOrderService.placeOrder4();

			int orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			int sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			int userId = placeOrderResp.getUserId();
			int tradingId = placeOrderResp.getTradingId();

			OrderCallService orderCallService = new OrderCallService();
			// 应付款全金额
			BigDecimal totalPrice = orderCallService
					.getNeedPrePayAmountOfCash(orderId);
			// 用余额支付金额
			BigDecimal blanceAmout = new BigDecimal(32);
			// 支付订单 余额+支付宝组合支付
			// 13 为 app国际支付宝，15 微信
			String payType = "13";
			int thirdTradingId = new OrderCallService().orderPayRequest(userId,
					blanceAmout, tradingId, payType);
			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall(payType,
					String.valueOf(thirdTradingId),
					totalPrice.subtract(blanceAmout).toString(), userId);
			// 等待支付网关异步处理
			Thread.sleep(10000);
			// 卖家接单
			orderCallService.acceptOrder(orderId, sellerId);
			// 发货
			orderCallService.dispatched(orderId, sellerId);
			// 修改发货时间为10天前，使其能自动确认收货
			new DefaultWapper().updateOrderDispathTimeByOrderId(orderId);
			// 冻结时间为当前时间20天前，使其能自动确认收货
			new DefaultWapper().updateOrderFrozenByOrderId(orderId);

			BigDecimal applyRefundAmout = new BigDecimal(130);

			// 申请退款
			ApplySalesRefundRequestBean applysalesrefundrequestBean = orderCallService
					.applySalesRefundRequestInJavaBean(orderId);
			applysalesrefundrequestBean.getSalesRefundInfoList().remove(1);
			applysalesrefundrequestBean.getSalesRefundInfoList().get(0)
					.setRefundAmount(applyRefundAmout);
			String refundBillNo = applysalesrefundrequestBean
					.getSalesRefundInfoList().get(0).getRefundBillNo();
			orderCallService
					.applySalesRefundRequestCall(applysalesrefundrequestBean);
			// 退款处理
			orderCallService
					.salesrefundsuccessrequest(applysalesrefundrequestBean);

			// 支付网关退款回调交易
			PayGateWayCallService.refundNotifyCall(payType,
					String.valueOf(thirdTradingId), userId);

			Thread.sleep(5000);
			// 确认收货请求
			confirmreceivebean.setOrderId(orderId);
			// 发送请求
			confirmreceivecall.setData(confirmreceivebean);
			confirmreceivecall.callService();
			Logger.verifyEquals("ok", confirmreceivecall.getReturnData(),
					"验证接口返回");
			DefaultWapper defaultWapper = new DefaultWapper();

			// 数据库验
			// 查询交易退款结算表
			List<Map> settlementInvoiceList = defaultWapper
					.selectYmtSettlementInvoice(orderId);
			// 订单商品表
			List<Map> orderInfoList = defaultWapper
					.selectOrderInfoByOderId(orderId);
			// 订单主表
			List<Map> ymtOrders = defaultWapper.selectOrderByOderId(orderId);
			// ymtOrderState 表
			List<Map> ymtOrderState = defaultWapper
					.selectOrderStateByOderId(orderId);
			// 计算退款按比例退的平台优惠券
			BigDecimal productYmtCouponValue = applyRefundAmout
					.multiply(
							(BigDecimal) ymtOrders.get(0).get(
									"fYmtCouponAmount"))
					.divide((BigDecimal) ymtOrders.get(0).get("fPayableAmount"),
							2, BigDecimal.ROUND_DOWN);
			Logger.comment("校验ymt_orders表");
			Logger.verifyEquals(4,
					(Integer) ymtOrders.get(0).get("iTradingStatus"),
					"验证iTradingStatus");
			Logger.verifyEquals(null, ymtOrders.get(0)
					.get("iSalesRefundStatus"), "验证iSalesRefundStatus");
			Logger.comment("校验ymt_orderstate表");
			DataUtil.verifyDecimalEquals(
					settlementInvoiceList
							.stream()
							.filter(account -> (Integer) account
									.get("BusinessType") == 2)
							.map(account -> (BigDecimal) account
									.get("CashAmount"))
							.reduce(BigDecimal.ZERO, BigDecimal::add),
					(BigDecimal) ymtOrderState.get(0).get(
							"fRefundedAmountOfCash"), "验证fRefundedAmountOfCash");
			DataUtil.verifyDecimalEquals(
					settlementInvoiceList
							.stream()
							.filter(account -> (Integer) account
									.get("BusinessType") == 2)
							.map(account -> (BigDecimal) account
									.get("fAccountAmount"))
							.reduce(BigDecimal.ZERO, BigDecimal::add),
					ymtOrderState.get(0).get("fRefundedAmountToAccount"),
					"验证fRefundedAmountToAccount");
			DataUtil.verifyDecimalEquals(
					settlementInvoiceList
							.stream()
							.filter(account -> (Integer) account
									.get("BusinessType") == 2)
							.map(account -> (BigDecimal) account
									.get("fThirdPartyAmount"))
							.reduce(BigDecimal.ZERO, BigDecimal::add),
					(BigDecimal) ymtOrderState.get(0).get(
							"fRefundedPaidAmountToThirdParty"),
					"验证fRefundedPaidAmountToThirdParty");

			Logger.verifyEquals(
					settlementInvoiceList
							.stream()
							.filter(account -> (Integer) account
									.get("BusinessType") == 1)
							.map(account -> (BigDecimal) account
									.get("CashAmount"))
							.reduce(BigDecimal.ZERO, BigDecimal::add),
					((BigDecimal) ymtOrderState.get(0).get("fPaidAmountOfCash"))
							.subtract((BigDecimal) ymtOrderState.get(0).get(
									"fRefundedAmountOfCash")),
					"验证确认收货后结算给商家的金额");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
}
